import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;


public class selectSplitPoint {
	private ArrayList<Data> examples;
	
	public selectSplitPoint(){
		examples = new FileReader("C:/Users/Worker/Desktop/CMU Tasks/task11/training.txt").getDataList();
	}
	
	public ArrayList<Data> getPerfectExamples(){
		ArrayList<Data> vacation = splitPoint(examples,InformationGain.Vacation);
		ArrayList<Data> eCredit = splitPoint(vacation,InformationGain.eCredit);
		ArrayList<Data> salary = splitPoint(eCredit,InformationGain.Salary);
		ArrayList<Data> proportion = splitPoint(salary,InformationGain.Property);
		return proportion;
	}
	
	
	/**
	 * 
	 * @param attribute
	 * @return
	 */
	public ArrayList<Data> splitPoint(ArrayList<Data> setOfExamples,int attribute){
		double min = 0;
		double max = 0;
		int k = setOfExamples.size();
		ArrayList<Double> points = new ArrayList<Double>();
		
		if(attribute == InformationGain.Vacation){
			Collections.sort(setOfExamples, new SortByVacation());	
			min = Double.parseDouble(setOfExamples.get(0).getAttribute(attribute));
			max = Double.parseDouble(setOfExamples.get(setOfExamples.size()-1).getAttribute(attribute));
		}
		if(attribute == InformationGain.eCredit){
			Collections.sort(setOfExamples, new SortByeCredit());	
			min = Double.parseDouble(setOfExamples.get(0).getAttribute(attribute));
			max = Double.parseDouble(setOfExamples.get(setOfExamples.size()-1).getAttribute(attribute));
		}
		if(attribute == InformationGain.Salary){
			Collections.sort(setOfExamples, new SortBySalary());
			min = Double.parseDouble(setOfExamples.get(0).getAttribute(attribute));
			max = Double.parseDouble(setOfExamples.get(setOfExamples.size()-1).getAttribute(attribute));
		}
		if(attribute == InformationGain.Property){
			Collections.sort(setOfExamples, new SortByProperty());
			min = Double.parseDouble(setOfExamples.get(0).getAttribute(attribute));
			max = Double.parseDouble(setOfExamples.get(setOfExamples.size()-1).getAttribute(attribute));
		}
		
		for(int i=1;i<=k;i++){
			points.add(min + i*((max-min)/(k+1)));		
		}
		return getConvertedExamples(setOfExamples,points,attribute);
	}
		
	/**
	 * 
	 * @param points
	 * @param attribute
	 * @return
	 */
	public ArrayList<Data> getConvertedExamples(ArrayList<Data> setOfExamples,ArrayList<Double> points, int attribute){
		InformationGain information = new InformationGain();
		HashMap<Double,Double> gainsSplitPoints = new HashMap<Double,Double>();
		HashMap<Double,ArrayList<Data>> examplesPoints = new HashMap<Double,ArrayList<Data>>();
		ArrayList<Double> gains = new ArrayList<Double>();
		double maxGain;
		double perfectPoint;
		ArrayList<Data> perfectExamples;
		
		for(int i=0;i<points.size();i++){
			double point = points.get(i);
			ArrayList<Data> convertedExamples = convert(setOfExamples,point,attribute);
			double informationGain = information.getGain(convertedExamples, attribute);	
			gains.add(informationGain);		
			gainsSplitPoints.put(informationGain, point);
			examplesPoints.put(point, convertedExamples);
		}
		
		Collections.sort(gains);	
		maxGain = gains.get(gains.size()-1);
		perfectPoint = gainsSplitPoints.get(maxGain);
		perfectExamples = examplesPoints.get(perfectPoint);
	
		return perfectExamples;
	}
	
	/**
	 * 
	 * @param splitPoint
	 * @param attribute
	 * @return
	 */
	public static ArrayList<Data> convert(ArrayList<Data> setOfExamples,double splitPoint,int attribute){
		ArrayList<Data> converted = new ArrayList<Data>();	
		
		//System.out.println("before converted examples: "+converted.toString());
		
		for(int i=0;i<setOfExamples.size();i++){
			Data data = new Data();
			for(int inner=0;inner<setOfExamples.get(i).size();inner++){
			    data.addAttribute(setOfExamples.get(i).getAttribute(inner));
			}
			converted.add(data);
		}
		
		/////////////////////////////////////////////////////
		//System.out.println("nunber of setOfExamples: "+setOfExamples.size());
		//System.out.println("original set of examples: "+setOfExamples.toString());
		//System.out.println("converted examples: "+converted.toString());
		
		for(int i = 0;i<converted.size();i++){
			try{
			    double value = Double.parseDouble(converted.get(i).getAttribute(attribute));
			    if(value<splitPoint){
			    	converted.get(i).updateAttribute(attribute, "<");
			    } else converted.get(i).updateAttribute(attribute, ">=");
			} catch (Exception e){
				System.out.println("Attribute is not number");
			}		
		}
		return converted;
	}
	
}
